-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Flight] Split Streaming from Relay Implemenation #18260
[Flight] Split Streaming from Relay Implemenation #18260
Conversation
This just forwards to the stream version of Flight which is itself forked between Node and W3C streams. The dom-relay goes directly to the Relay config though which allows it to avoid the stream part of Flight.
This decouples it so that the Relay implementation doesn't have to encode the JSON to strings. Instead it can be fed the values as JSON objects and do its own encoding.
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit b906235:
|
Details of bundled changes.Comparing: bdc5cc4...b906235 react-flight-dom-relay
react-flight-dom-webpack
react-server
Size changes (stable) |
Details of bundled changes.Comparing: bdc5cc4...b906235 react-flight-dom-relay
react-flight-dom-webpack
react-server
Size changes (experimental) |
Same split as the server.
9686ab4
to
5a5fae4
Compare
This requires an external helper file that we'll wire up internally.
5a5fae4
to
b906235
Compare
let response = createResponse(data); | ||
for (let i = 0; i < data.length; i++) { | ||
processStringChunk(response, data[i], 0); | ||
function parseModel(response, targetObj, key, value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key
seems unused?
To clarify, this is the result of calling a Block's load function, right? So it's the curried Block Query function plus its arguments. |
Yea, that's correct. We still need a name for that. 😂 |
Thunk? |
Sorry for multiple rounds of questions, but who calls the client methods like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This layering makes sense, thanks for abstracting out the representation.
} | ||
complete(response); | ||
return getModelRoot(response); | ||
return parseModelFromJSON(response, targetObj, key, value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"key" is used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦♂
@josephsavona No. Relay calls resolveModel and resolveError when it receives that "chunk" from the server. So you encode model and error however you want on the server and then parse it on the client and feed it back into Flight. ID = 0 is special. It's the root and is always emitted first. So you could for example inline that in the response and then stream in the rest. |
Ah got it, so inverse of the server. Cool cool. |
This splits the Flight implementation into a general JSON chunk part and a streaming part. The default implementation goes to a binary/string stream API which varies between Node and W3C streams. The Relay implementation by-passes the serialization and instead gets passed JSON-serializable object chunks.
The server configs are layered like this:
The client is a bit simpler. The implementation just imports ReactFlightClient (used by Relay) or ReactFlightClientStream (used by Streams).
Flight Relay Server Bindings
The API for the server is:
The first argument is something that can be returned from a Block. I.e. the root model. Something JSONable. This will change to require a Block. The second argument is whatever Relay wants to the target to be.
This also depends on an external file that we'll have to add to www:
ReactFlightDOMRelayServerIntegration.js
. This will needs to implement the following API:This will be called asynchronously as ReactFlight completes part of the model. Once there's no more to render, it'll call
close()
on the destination. Relay can then serialize these rows as it wants.Flight Relay Client Bindings
The client API is:
To use this, you first have to create a "response". You can get a model out of the response which will just have placeholders in it. This particular API will change as I get rid of "proxies". It’ll return a Block instead. The principle is that it can return something even before any data has loaded so you immediately get something that can suspend.
The resolveModel and resolveError are called as new rows stream in.
close
should be called when there's no more rows or the connection dies (even if it dies early).